

namespace Nutils
{
    public class File
    {
        static public System.Text.Encoding DeduceEncoding(string filepath, System.Text.Encoding fallback)
        {
            if (null == _impl)
            {
                return fallback;
            }

            return _impl.FindEncoding(filepath,fallback);
        }

        static public void Unpack(XML.Tree xmlTree)
        {
            _impl = new Impl(xmlTree);
        }

        ///
        /// Private Impl
        /// 

        static private Impl _impl;
        private class Impl
        {
            private System.Collections.Generic.Dictionary<string, System.Text.Encoding> _map;

            private struct NameEncodingPair
            {
                public string name;
                public System.Text.Encoding encoding;
                public NameEncodingPair(string n, System.Text.Encoding e)
                {
                    name = n;
                    encoding = e;
                }
            }

            public Impl(XML.Tree xmlTree)
            {
                NameEncodingPair[] pairs = new NameEncodingPair[5] { 
                    new NameEncodingPair( "ASCII", System.Text.Encoding.ASCII ), 
                    new NameEncodingPair( "UTF32", System.Text.Encoding.UTF32 ),
                    new NameEncodingPair( "UTF16", System.Text.Encoding.Unicode ), 
                    new NameEncodingPair( "UTF8", System.Text.Encoding.ASCII ),
                    new NameEncodingPair( "UTF7", System.Text.Encoding.UTF7 ) 
                };

                _map = new System.Collections.Generic.Dictionary<string, System.Text.Encoding>();

                foreach (XML.Tree typemap_node in xmlTree.ForEach("FileTypeMapping"))
                {
                    foreach (NameEncodingPair pair in pairs)
                    {
                        foreach (XML.Tree matched_node in typemap_node.ForEach(pair.name))
                        {
                            string file_extensions = matched_node.text.ToLower();
                            foreach( string ext in file_extensions.Split(' ') )
                            {
                                _map.Add(ext, pair.encoding);
                            }
                        }
                    }
                }
            }

            public System.Text.Encoding FindEncoding(string filepath, System.Text.Encoding fallback)
            {
                int index = filepath.LastIndexOf('.');
                if (-1 == index)
                {
                    return fallback;
                }

                string extension = filepath.Substring(index+1).ToLower();
                if (!_map.ContainsKey(extension))
                {
                    return fallback;
                }

                return _map[extension];
            }
        }

    }

}